package com.ai.web.weixin;

import java.lang.reflect.Field;
import java.util.Map;

import org.apache.log4j.Logger;

import com.ai.web.cache.SpringContextUtil;
import com.ai.web.weixin.message.request.ClickMessage;
import com.ai.web.weixin.message.request.ImageMessage;
import com.ai.web.weixin.message.request.LinkMessage;
import com.ai.web.weixin.message.request.LocationMessage;
import com.ai.web.weixin.message.request.ReqBaseMessage;
import com.ai.web.weixin.message.request.ScanMessage;
import com.ai.web.weixin.message.request.TextMessage;
import com.ai.web.weixin.message.request.VoiceMessage;
import com.ai.web.weixin.message.util.MessageUtil;
import com.ai.web.weixin.processor.ClickMsgProcessor;
import com.ai.web.weixin.processor.FollowMsgProcessor;
import com.ai.web.weixin.processor.IMessageProcessor;
import com.ai.web.weixin.processor.ImageMsgProcessor;
import com.ai.web.weixin.processor.LinkMsgProcessor;
import com.ai.web.weixin.processor.LocationMsgProcessor;
import com.ai.web.weixin.processor.ScanMsgProcessor;
import com.ai.web.weixin.processor.TextMsgProcessor;
import com.ai.web.weixin.processor.UnFollowMsgProcessor;
import com.ai.web.weixin.processor.VoiceMsgProcessor;

public class MessageDispatch {
	
	private static Logger logger = Logger.getLogger(MessageDispatch.class);

	public static String dispatch(Map<String, String> msgMap) {
		// 消息类型  
        String msgType = msgMap.get("MsgType");
        
        IMessageProcessor processor = null;
        ReqBaseMessage bm = null;
        // 文本消息  
        if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {  
        	logger.info("您发送的是文本消息！");
        	bm = new TextMessage();
            converReqMsg(msgMap, bm);
            processor = (TextMsgProcessor) 
        			SpringContextUtil.getBean("textMsgProcessor");
        }  
        // 图片消息  
        else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) { 
        	logger.info("您发送的是图片消息！");
        	bm = new ImageMessage();
            converReqMsg(msgMap, bm);
            processor = (ImageMsgProcessor) 
        			SpringContextUtil.getBean("imageMsgProcessor");
        }  
        // 地理位置消息  
        else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) {  
        	logger.info("您发送的是地理位置消息！");  
        	bm = new LocationMessage();
            converReqMsg(msgMap, bm);
            processor = (LocationMsgProcessor) 
        			SpringContextUtil.getBean("locationMsgProcessor");
        }  
        // 链接消息  
        else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) {  
        	logger.info("您发送的是链接消息！");  
        	bm = new LinkMessage();
            converReqMsg(msgMap, bm);
            processor = (LinkMsgProcessor) 
        			SpringContextUtil.getBean("linkMsgProcessor");
        }  
        // 音频消息  
        else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) {  
        	logger.info("您发送的是音频消息！"); 
        	bm = new VoiceMessage();
            converReqMsg(msgMap, bm);
            processor = (VoiceMsgProcessor) 
        			SpringContextUtil.getBean("voiceMsgProcessor");
        }  
        // 事件推送  
        else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {  
            // 事件类型  
            String eventType = msgMap.get("Event");  
            // 订阅  
            if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {  
            	logger.info("收到关注！");  
            	
            	bm = new ReqBaseMessage();
            	converReqMsg(msgMap, bm);
            	processor = (FollowMsgProcessor) 
            			SpringContextUtil.getBean("followMsgProcessor");
            }  
            // 取消订阅  
            else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) {  
            	logger.info("取消关注！");
            	bm = new ReqBaseMessage();
            	converReqMsg(msgMap, bm);
            	processor = (UnFollowMsgProcessor) 
            			SpringContextUtil.getBean("unfollowMsgProcessor");
            	
            }  
            // 自定义菜单点击事件  
            else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {  
            	String eventKey = msgMap.get("EventKey");
            	logger.info("收到click event key=" + eventKey);
            	
            	bm = new ClickMessage();
            	converReqMsg(msgMap, bm);
            	processor = (ClickMsgProcessor) 
            			SpringContextUtil.getBean("clickMsgProcessor");
            } 
            // 扫描事件  
            else if (eventType.equals(MessageUtil.EVENT_TYPE_SCAN)) {  
            	String eventKey = msgMap.get("EventKey");
            	logger.info("收到scan event key=" + eventKey);
            	
            	bm = new ScanMessage();
            	converReqMsg(msgMap, bm);
            	processor = (ScanMsgProcessor) 
            			SpringContextUtil.getBean("scanMsgProcessor");
            }
        }  
        
        if (processor != null && bm != null) {
        	return processor.process(bm);
        } else {
        	logger.error("Can't dispatch msg! " + msgMap);
        }
        
        return null;
	}
	
	private static void converReqMsg(Map<String, String> msgMap, ReqBaseMessage obj) {
		try {
			Class<ReqBaseMessage> bmClazz = (Class<ReqBaseMessage>) obj.getClass();
			Field[] superFs = bmClazz.getSuperclass().getDeclaredFields();
			Field[] fs = bmClazz.getDeclaredFields();
			
			for (String fieldName : msgMap.keySet()) {
				
				Field field = null;
				for (Field f : superFs) {
					if (f.getName().equals(fieldName)) {
						field = f;
						break;
					}
				}
				if (field == null) {
					for (Field f : fs) {
						if (f.getName().equals(fieldName)) {
							field = f;
							break;
						}
					}
				}
				if (field == null) {
					logger.error("Can't find field key=" + fieldName);
				} else {
					field.setAccessible(true);
					field.set(obj, msgMap.get(fieldName));
				}
			}
		} catch(Exception e) {
			logger.error(e.getMessage(), e);
		}
	}
	
	
	
}
